package com.yeyks.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.yeyks.constant.ConfigKey;
import com.yeyks.dal.dao.UserAccountOverviewMapper;
import com.yeyks.dal.dao.UserBillMapper;
import com.yeyks.dal.domain.UserAccountOverview;
import com.yeyks.dal.domain.UserBill;
import com.yeyks.dal.domain.UserInfo;
import com.yeyks.dto.UserAccountOverviewDTO;
import com.yeyks.exception.ServiceException;
import com.yeyks.service.ConfigService;
import com.yeyks.service.RechargeRecordService;
import com.yeyks.service.UserAccountOverviewService;
import com.yeyks.service.UserInfoService;
import com.yeyks.util.ObjectConvertUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author fuchangshuai
 * @date 2019/4/23 0023
 */
@Service
@Slf4j
public class UserAccountOverviewServiceImpl implements UserAccountOverviewService {

    @Autowired
    private UserBillMapper userBillMapper;
    @Autowired
    private UserAccountOverviewMapper overviewMapper;
    @Autowired
    private RechargeRecordService recordService;
    @Autowired
    private ConfigService configService;

    /**
     * 通过用户的id查询用户账户信息(没有则创建)
     *
     * @param userId
     * @return
     */
    @Override
    public UserAccountOverview getUserAccountNoCreate(Integer userId) {
        UserAccountOverview account = overviewMapper.selectByUserId(userId);
        if (account == null) {
            account = getUserAccount(userId);
            int res = overviewMapper.insert(account);
            if (res != 1) {
                log.error("用户账户创建异常userId = {}", userId);
                return null;
            }
        }
        return account;
    }

    /**
     * 增加账户金额
     *
     * @param amount 操作金额数
     * @param userId 用户id
     * @param remark 备注
     * @param type   账单类型：1 充值 2 佣金 3、提现 4、消费
     * @return
     */
    @Override
    @Transactional
    public Boolean addAmount(Integer amount, Integer userId, Integer type, String remark) {
        try {
            if (amount == null) {
                amount = 0;
            }
            UserAccountOverview account = getUserAccountNoCreate(userId);
            if (account == null) {
                return false;
            }
            account.setTotalInAmount(account.getTotalInAmount() == null ? 0 : account.getTotalInAmount() + amount);
            int outAmount = account.getOutAmount() == null ? 0 : account.getOutAmount();
            account.setRemainAmount(account.getTotalInAmount() - outAmount < 0 ? 0 : account.getTotalInAmount() - outAmount);
            overviewMapper.updateByPrimaryKey(account);
            UserBill userBill = getUserBill(account, amount, remark, type);
            return userBillMapper.insert(userBill) == 1;
        } catch (Exception e) {
            log.error("增加账户金额异常{}", e.getLocalizedMessage());
            return false;
        }
    }

    /**
     * 减少账户金额
     *
     * @param amount 操作金额数
     * @param userId 用户id
     * @param remark 备注
     * @param type   账单类型：1 充值 2 佣金 3、提现 4、消费
     * @return
     */
    @Override
    @Transactional
    public Boolean descAmount(Integer amount, Integer userId, Integer type, String remark) {
        try {
            if (amount == null) {
                amount = 0;
            }
            UserAccountOverview account = getUserAccountNoCreate(userId);
            if (account == null) {
                log.info("账户信息为空{}", userId);
                throw new ServiceException("账户信息为空");
            }
            if (amount > account.getRemainAmount()) {
                log.info("减少账户余额失败,消费金额{}，账户余额{}", amount, account.getTotalInAmount());
                throw new ServiceException("账户余额不足");
            }
            account.setOutAmount(account.getOutAmount() == null ? 0 : account.getOutAmount() + amount);
            account.setRemainAmount(account.getTotalInAmount() - account.getOutAmount());
            overviewMapper.updateByPrimaryKey(account);
            UserBill userBill = getUserBill(account, amount, remark, type);
            return userBillMapper.insert(userBill) == 1;
        } catch (ServiceException e) {
            throw new ServiceException(e.getMessage());
        } catch (Exception e) {
            log.error("减少账户金额异常{}", e.getLocalizedMessage());
            return false;
        }
    }

    /**
     * 获取用户账户等相关信息
     *
     * @param userInfo
     * @return
     */
    @Override
    public UserAccountOverviewDTO info(UserInfo userInfo) {
        UserAccountOverviewDTO userAccountOverviewDTO = null;
        try {
            UserAccountOverview account = getUserAccountNoCreate(userInfo.getId());
            userAccountOverviewDTO = ObjectConvertUtil.convertObject(account, UserAccountOverviewDTO.class);
            userAccountOverviewDTO.setInviteId(userInfo.getInviteCode());
            //获取推广人数
            Integer count = recordService.selectCountByInviteId(userInfo.getInviteCode());
            userAccountOverviewDTO.setPeopleSize(count);
            userAccountOverviewDTO.setUrl(getUrl());
        } catch (Exception e) {
            log.error("获取用户账户等相关信息异常{}", e.getLocalizedMessage());
            e.printStackTrace();
        }
        return userAccountOverviewDTO;
    }

    private String getUrl() {
        try {
            String value = configService.getValue(ConfigKey.ACTIVITY_PAY_URL);
            JSONObject jsonObject = JSONObject.parseObject(value);
            return (String) jsonObject.get("url");

        } catch (Exception e) {
            log.error("获取活动充值链接异常{}", e.getLocalizedMessage());
//            return "https://kuaisu.chengguokj.com/activity/promotion";
            return null;
        }

    }

    private UserBill getUserBill(UserAccountOverview account, Integer amount, String remark, Integer type) {
        UserBill userBill = new UserBill();
        userBill.setAvaliableAmount(Long.valueOf(account.getRemainAmount()));
        userBill.setOperatorAmount(Long.valueOf(amount));
        userBill.setRemark(remark);
        userBill.setType(type);
        userBill.setUserId(account.getUserId());
        return userBill;
    }

    private UserAccountOverview getUserAccount(Integer userId) {
        UserAccountOverview overview = new UserAccountOverview();
        overview.setTotalInAmount(0);
        overview.setUserId(Long.valueOf(userId));
        overview.setRemainAmount(0);
        overview.setOutAmount(0);
        return overview;
    }
}
